package cd.usbhelper;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


public class UsbHelperClient {

    /** 操作成功  **/
    public static final int USB_OPERATE_OK = 0;
    /** 连接设备失败  **/
    public static final int USB_CONNECT_FAILED = -401;
    /** 没有权限连接usb设备  **/
    public static final int USB_CONNECT_NOPERMISSION = -402;
    /** 还未连接，请先调用connect()  **/
    public static final int USB_NOT_CONNECT = -403;
    /** USB读取数据超时  **/
    public static final int USB_READ_TIMEOUT = -404;
    
    private static final String TAG = "cd";
	public static final String ACTION_DEVICE_PERMISSION = "cd.usb.USB_PERMISSION";
	private Context mContext;
	//设备列表
    private HashMap<String, UsbDevice> deviceList;
    //USB管理器:负责管理USB设备的类
    private UsbManager manager;
    private UsbDevice mUsbDevice;
    private UsbInterface mUsbInterface;
    private IUsbhelperListener mListener;
    
    private UsbDeviceConnection mDeviceConnection;
    //代表一个接口的某个节点的类:写数据节点
//    private UsbEndpoint usbEpOut;
    //代表一个接口的某个节点的类:读数据节点
//    private UsbEndpoint usbEpIn;

	public UsbHelperClient(Context context){
		// 获取USB设备
		mContext = context.getApplicationContext();
        manager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
         
	}
	
	public HashMap<String, UsbDevice> getDeviceList(){
		//获取到设备列表
        deviceList = manager.getDeviceList();
        return deviceList;
	}
	
	public UsbInterface getUsbInterface(UsbDevice usbDevice , int index){
		// 一般来说一个设备都是一个接口，你可以通过getInterfaceCount()查看接口的个数
        // 这个接口上有两个端点，分别对应OUT 和 IN
		return usbDevice.getInterface(index);
	}
    public void disConnectDevice(){
        if(mDeviceConnection != null){
            mDeviceConnection.close();
            mDeviceConnection = null;
        }
        if(mUsbReceiver!=null)
            mContext.unregisterReceiver(mUsbReceiver);

    }
	public void connectDevice(UsbDevice usbDevice, IUsbhelperListener listener){
		connectDevice(usbDevice,usbDevice.getInterface(0), listener);
	}
	public void connectDevice(UsbDevice usbDevice, UsbInterface usbInterface, IUsbhelperListener listener){
		mUsbDevice = usbDevice;
		mUsbInterface = usbInterface;
		mListener = listener;
        if (mUsbInterface != null) {
            // 判断是否有权限
            if (manager.hasPermission(mUsbDevice)) {
            	connect();
            } else {
                requestUsbOperationPermission();
            }
        } else {
        	Log.d("TAG","没有找到设备接口！");
        	mListener.onError(USB_CONNECT_FAILED); 
        }
        
	}
    private UsbReceiver mUsbReceiver;
	private void requestUsbOperationPermission(){
		PendingIntent mPermissionIntent = PendingIntent.getBroadcast(mContext,0,new Intent(ACTION_DEVICE_PERMISSION),0);
        IntentFilter permissionFilter = new IntentFilter(ACTION_DEVICE_PERMISSION);
        mUsbReceiver = new UsbReceiver();
        mContext.registerReceiver(mUsbReceiver,permissionFilter);
        manager.requestPermission(mUsbDevice,mPermissionIntent);
	}
	private void connect(){
		// 打开设备，获取 UsbDeviceConnection 对象，连接设备，用于后面的通讯
        mDeviceConnection = manager.openDevice(mUsbDevice);
        if (mDeviceConnection == null) {
        	mListener.onError(USB_CONNECT_FAILED);
        	return;
        }
        if (mDeviceConnection.claimInterface(mUsbInterface, true)) {
            //用UsbDeviceConnection 与 UsbInterface 进行端点设置和通讯
            int epCount = mUsbInterface.getEndpointCount();
            List<UsbEndpoint> listUsbEp = new ArrayList<>();
            for(int i = 0; i < epCount;i++)
                listUsbEp.add(mUsbInterface.getEndpoint(i));
            mListener.onSuccess(mDeviceConnection,listUsbEp);
//            usbEpOut = mUsbInterface.getEndpoint(1);
//            usbEpIn = mUsbInterface.getEndpoint(0);
        } else {
            mDeviceConnection.close();
            mDeviceConnection = null;
            mListener.onError(USB_CONNECT_FAILED); 
        }
	}
    public boolean isConnected(){
	    if(mDeviceConnection==null)
	        return false;
        return mDeviceConnection.getFileDescriptor()>=0;
    }


    private class UsbReceiver extends BroadcastReceiver {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_DEVICE_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        if (device != null) {
                        	Log.d(TAG, "device != null");
                        	connect();
                        }
                    } else {
                    	mListener.onError(USB_CONNECT_NOPERMISSION);
                    }
                }
                mContext.unregisterReceiver(mUsbReceiver);
                mUsbReceiver = null;
            } 
        }
    };
    
    
    public int sendMessage(UsbEndpoint usbEpOut,byte[] send_cmd,int timeout) {
    	if(mDeviceConnection == null){
    		return USB_NOT_CONNECT;
    	}

        return mDeviceConnection.bulkTransfer(usbEpOut, send_cmd, send_cmd.length, timeout);
//        return sendMessage(mDeviceConnection,usbEpOut,send_cmd,timeout);
    }
    public int readMessage(UsbEndpoint usbEpIn,byte[] response_cmd,int timeout)
    {
    	if(mDeviceConnection == null){
    		return USB_NOT_CONNECT;
    	}
    	return mDeviceConnection.bulkTransfer(usbEpIn, response_cmd, response_cmd.length, timeout);
//        return readMessage(mDeviceConnection,usbEpIn,response_cmd, timeout);
    }

    public native int sendMessage(UsbDeviceConnection deviceConnection, UsbEndpoint usbEpOut, byte[] send_cmd, int timeout);
    public native int readMessage(UsbDeviceConnection deviceConnection, UsbEndpoint usbEpIn, byte[] response_cmd, int timeout);

    static {
        System.loadLibrary("tools_v2.1");
    }

//    private void readFromUsb() {
//        //读取数据2
//        int outMax = usbEpOut.getMaxPacketSize();
//        int inMax = usbEpIn.getMaxPacketSize();
//        ByteBuffer byteBuffer = ByteBuffer.allocate(inMax);
//        UsbRequest usbRequest = new UsbRequest();
//        usbRequest.initialize(mDeviceConnection, usbEpIn);
//        usbRequest.queue(byteBuffer, inMax);
//        if (mDeviceConnection.requestWait() == usbRequest) {
//            byte[] retData = byteBuffer.array();
//            try {
//                showTmsg("收到数据：" + new String(retData, "UTF-8"));
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//            }
//        }
//    }
	
}






